home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / clonecd / September 93.img / Archives / Applications / Assorted Programs / PCB Cad / PCBVIEW.C < prev    next >
C/C++ Source or Header  |  1990-10-13  |  15KB  |  507 lines

  1. /*
  2. ** printed circuit board displayer, Copyright (C) Randy Nevin 1989.
  3. **
  4. ** you may give this software to anyone, make as many copies as you like, and
  5. ** post it on public computer bulletin boards and file servers. you may not
  6. ** sell it or charge any fee for distribution (except for media and postage),
  7. ** remove this comment or the copyright notice from the code, or claim that
  8. ** you wrote this code or anything derived from it. you may modify the code as
  9. ** much as you want (please document clearly with comments, and maintain the
  10. ** coding style), but programs which are derived from this one are subject to
  11. ** the conditions stated here. i am providing this code so that people can
  12. ** learn from it, so if you distribute it, please include source code, not
  13. ** just executables. contact me to report bugs or suggest enhancements; i do
  14. ** not guarantee support, but i will make an effort in good faith to help you,
  15. ** and i want to act as a central clearing house for future versions. you
  16. ** should contact me before undertaking a significant development effort, to
  17. ** avoid reinventing the wheel. if you come up with an enhancement you
  18. ** consider particularly useful, i would appreciate being informed so that it
  19. ** can be incorporated in future versions. my address is: Randy Nevin,
  20. ** 1731 211th PL NE, Redmond, WA 98053. this code is available directly from
  21. ** the author; just send a floppy and a self-addressed floppy mailer with
  22. **
  23. ** HISTORY
  24. ** (name        date        description)
  25. ** ----------------------------------------------------
  26. ** randy nevin        2/1/89        initial version
  27. ** randy nevin        2/11/89        released version 1.00
  28. */
  29.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. /*#include <io.h>*/
  33. /*#include <conio.h>*/
  34. #include <string.h>
  35. /*#include <dos.h>*/
  36. /* #include <signal.h> enable this to catch ^C */
  37. #include "cell.h"
  38.  
  39. #ifdef THINK_C
  40. #include <console.h>
  41. #endif
  42.  
  43. extern WindowPtr gPictWindow;
  44.  
  45. /*
  46. ** ^C handling is disabled because on my system enabling it seems to interfere
  47. ** with int 10h processing, which is needed to plot pixels. you should enable
  48. ** it and see what happens on your system.
  49. */
  50.  
  51. /* WARNING: the code below assumes 640x350 16-color ega */
  52.  
  53. /* 0=black    1=blue        2=green        3=light blue        */
  54. /* 4=red    5=purple    6=brown        7=grey            */
  55. /* 8=black    9=bright blue    A=bright green    B=bright light blue    */
  56. /* C=scarlet    D=purple    E=yellow    F=white            */
  57.  
  58. /*
  59. ** the colors below work fine for me, but may not for your particular ega and
  60. ** monitor. if bright blue and light blue look the same to you, or some traces
  61. ** appear to be missing, you may want to change these constants.
  62. **
  63. ** on some egas, there appear to be gaps in the traces; i don't know why. on
  64. ** other egas, the traces look fine. this happened to me on the maximum zoom,
  65. ** but not on any other zoom level. apparently some problem with the int 10h
  66. ** interface.
  67. */
  68.  
  69. /* colors of objects */
  70. #define H    0xC    /* hole color; scarlet            */
  71. #define F    0x9    /* frontside trace color; bright blue    */
  72. #define B    0x3    /* backside trace color; light blue    */
  73. #define E    0xE    /* edge color; yellow            */
  74.  
  75. /* screen limits */
  76. #define MINHORZ    0    /* left-most pixel    */
  77. #define MAXHORZ    639    /* right-most pixel    */
  78. #define MINVERT    0    /* top-most pixel    */
  79. #define MAXVERT    349    /* bottom-most pixel    */
  80.  
  81. static int mode; /* for saving original screen mode */
  82. static int sides = 3; /* 0=holes only, 1=front only, 2=back only, 3=all */
  83.  
  84. #define MAXZOOM    3    /* maximum zoom number; minimum is 0 */
  85.  
  86. #define ZOOM0    3    /* 3x3 pixels per cell        */
  87. #define ZOOM1    6    /* 6x6 pixels per cell        */
  88. #define ZOOM2    10    /* 10x10 pixels per cell    */
  89. #define ZOOM3    18    /* 18x18 pixels per cell    */
  90.  
  91. static int zoom = 1; /* 0=3x3, 1=6x6, 2=10x10, 3=18x18 */
  92. static int zoomsize[MAXZOOM+1] = { ZOOM0, ZOOM1, ZOOM2, ZOOM3 };
  93.  
  94. /* current lower-left position */
  95. static int Xrow = 0;
  96. static int Xcol = 0;
  97.  
  98. int justboard = 1; /* only need the board data structure */
  99.  
  100. /* board dimensions */
  101. extern int Nrows;
  102. extern int Ncols;
  103.  
  104. extern void InitBoard( void );
  105. extern long GetCell( int, int, int );
  106. extern void SetCell( int, int, int, long );
  107. /*extern int GetMode( void );
  108. extern void SetMode( int );
  109. extern void Dot( int, int, int );*/
  110.  
  111. void main( int, char *[] );
  112. /* static void control_C( void ); enable this to catch ^C */
  113. static void doedges( void );
  114. static void doboard( void );
  115. static void map( int, int, long, long );
  116. static void plot0( int, int, char [ZOOM0][ZOOM0], int );
  117. static void plot1( int, int, char [ZOOM1][ZOOM1], int );
  118. static void plot2( int, int, char [ZOOM2][ZOOM2], int );
  119. static void plot3( int, int, char [ZOOM3][ZOOM3], int );
  120.  
  121. void main ( argc, argv ) /* input routed board, display it on the screen */
  122.     int argc;
  123.     char *argv[];
  124.     {
  125.     char *self, *p;
  126.     int r, c, rp, cp, i1, i2, i3, i4;
  127.     FILE *fp;
  128.     long x;
  129.     /*union REGS regs;*/
  130.     GrafPtr        oldPort;
  131.     
  132. #ifdef THINK_C
  133.     argc = ccommand (&argv);        /* simulate command-line arguments */
  134. #endif
  135.  
  136.     SetUpMacInt();
  137.     
  138.     printf( "Copyright (C) Randy Nevin, 1989. Version 1.00\n" );
  139.     printf( "See source code for rights granted.\n\n" );
  140.     self = argv[0];
  141.     /* get rid of initial part of path */
  142.     if ((p = strrchr( self, '\\' )) || (p = strrchr( self, ':' )))
  143.         self = ++p;
  144.     if (argc != 2) { /* need infile */
  145.         fprintf( stderr, "usage: %s infile\n", self );
  146.         exit( -1 );
  147.         }
  148.     if (!(fp = fopen( argv[1], "rb" ))) {
  149.         fprintf( stderr, "can't open %s\n", argv[1] );
  150.         exit( -1 );
  151.         }
  152.     /* fetch the board dimensions */
  153.     if ((rp = getc( fp )) == EOF || (cp = getc( fp )) == EOF) {
  154.         fprintf( stderr, "premature eof\n" );
  155.         exit( -1 );
  156.         }
  157.     Nrows = (rp & 0xFF) | ((cp << 8) & 0xFF00);
  158.     if ((rp = getc( fp )) == EOF || (cp = getc( fp )) == EOF) {
  159.         fprintf( stderr, "premature eof\n" );
  160.         exit( -1 );
  161.         }
  162.     Ncols = (rp & 0xFF) | ((cp << 8) & 0xFF00);
  163.     InitBoard(); /* allocate memory for data structures */
  164.     for (r = 0; r < Nrows; r++) { /* read in the board, row by column */
  165.         for (c = 0; c < Ncols; c++) {
  166.             /* first, do frontside */
  167.             if ((i1 = getc( fp )) == EOF
  168.                 || (i2 = getc( fp )) == EOF
  169.                 || (i3 = getc( fp )) == EOF
  170.                 || (i4 = getc( fp )) == EOF) {
  171.                 fprintf( stderr, "premature eof\n" );
  172.                 exit( -1 );
  173.                 }
  174.             x = (long)i1 | (((long)i2) << 8)
  175.                 | (((long)i3) << 16) | (((long)i4) << 24);
  176.             SetCell( r, c, TOP, x );
  177.             /* then do backside */
  178.             if ((i1 = getc( fp )) == EOF
  179.                 || (i2 = getc( fp )) == EOF
  180.                 || (i3 = getc( fp )) == EOF
  181.                 || (i4 = getc( fp )) == EOF) {
  182.                 fprintf( stderr, "premature eof\n" );
  183.                 exit( -1 );
  184.                 }
  185.             x = (long)i1 | (((long)i2) << 8)
  186.                 | (((long)i3) << 16) | (((long)i4) << 24);
  187.             SetCell( r, c, BOTTOM, x );
  188.             }
  189.         }
  190.     /* tell user what commands are available */
  191.     printf( "\t0   = holes only\n" );
  192.     printf( "\t1   = holes and top traces\n" );
  193.     printf( "\t2   = holes and bottom traces\n" );
  194.     printf( "\t3   = holes and all traces\n" );
  195.     printf( "\tz/Z = zoom one level / maximum zoom\n" );
  196.     printf( "\ts/S = shrink one level / minimum shrink\n" );
  197.     printf( "\tl/L = move left by one / move left by ten\n" );
  198.     printf( "\tr/R = move right by one / move right by ten\n" );
  199.     printf( "\tu/U = move up by one / move up by ten\n" );
  200.     printf( "\td/D = move down by one / move down by ten\n" );
  201.     printf( "\tany other key exits the program\n" );
  202.     printf( "\nPress ENTER to continue, or ^C to exit " );
  203.     /*regs.h.ah = 0x8;  character input without echo */
  204.     /*intdos( ®s, ®s );  call dos to get a keystroke */
  205.     /*mode = GetMode();  save mode so can restore later */
  206.     /* signal( SIGINT, control_C ); enable this to catch ^C */
  207.     /*SetMode( 0x10 );  640x350 16-color mode */
  208.     GetPort ( &oldPort );
  209.     ShowWindow ( gPictWindow );
  210.     SelectWindow ( gPictWindow );
  211.     SetPort ( gPictWindow );
  212.     SetOrigin ( -10, 100 );
  213.     doedges(); /* display board edges */
  214.     doboard(); /* display the board */
  215.     for (;;) { /* process until unrecognized keystroke */
  216.         /*regs.h.ah = 0x8;  character input without echo */
  217.         /*intdos( ®s, ®s );  call dos to get a keystroke */
  218.         switch ( getKey()    /*regs.h.al*/) { /* determine what it is */
  219.         case '0': /* just show holes */
  220.             if (sides == 0)
  221.                 continue;
  222.             sides = 0;
  223.             break;
  224.         case '1': /* show holes and top-side traces */
  225.             if (sides == 1)
  226.                 continue;
  227.             sides = 1;
  228.             break;
  229.         case '2': /* show holes and bottom-side traces */
  230.             if (sides == 2)
  231.                 continue;
  232.             sides = 2;
  233.             break;
  234.         case '3': /* show holes and all traces */
  235.             if (sides == 3)
  236.                 continue;
  237.             sides = 3;
  238.             break;
  239.         case 'Z': /* zoom to the limit */
  240.             if (zoom == MAXZOOM)
  241.                 continue;
  242.             zoom = MAXZOOM;
  243.             break;
  244.         case 'z': /* zoom by one */
  245.             if (zoom == MAXZOOM)
  246.                 continue;
  247.             zoom++;
  248.             break;
  249.         case 'S': /* shrink to the limit */
  250.             if (zoom == 0)
  251.                 continue;
  252.             zoom = 0;
  253.             break;
  254.         case 's': /* shrink by one */
  255.             if (zoom == 0)
  256.                 continue;
  257.             zoom--;
  258.             break;
  259.         case 'L': /* left by 10 */
  260.             if (Xcol == 0)
  261.                 continue;
  262.             if (Xcol <= 10)
  263.                 Xcol = 0;
  264.             else
  265.                 Xcol -= 10;
  266.             break;
  267.         case 'l': /* left by one */
  268.             if (Xcol == 0)
  269.                 continue;
  270.             Xcol--;
  271.             break;
  272.         case 'R': /* right by 10 */
  273.             if (Xcol == Ncols-1)
  274.                 continue;
  275.             if (Xcol >= Ncols-11)
  276.                 Xcol = Ncols-1;
  277.             else
  278.                 Xcol += 10;
  279.             break;
  280.         case 'r': /* right by one */
  281.             if (Xcol == Ncols-1)
  282.                 continue;
  283.             Xcol++;
  284.             break;
  285.         case 'U': /* up by 10 */
  286.             if (Xrow == Nrows-1)
  287.                 continue;
  288.             if (Xrow >= Nrows-11)
  289.                 Xrow = Nrows-1;
  290.             else
  291.                 Xrow += 10;
  292.             break;
  293.         case 'u': /* up by one */
  294.             if (Xrow == Nrows-1)
  295.                 continue;
  296.             Xrow++;
  297.             break;
  298.         case 'D': /* down by 10 */
  299.             if (Xrow == 0)
  300.                 continue;
  301.             if (Xrow <= 10)
  302.                 Xrow = 0;
  303.             else
  304.                 Xrow -= 10;
  305.             break;
  306.         case 'd': /* down by one */
  307.             if (Xrow == 0)
  308.                 continue;
  309.             Xrow--;
  310.             break;
  311.         case 'q' : 
  312.             ExitToShell ();
  313.             break;
  314.         default:
  315.             /*SetMode( mode );  restore original screen mode */
  316.             /*exit( 0 );*/
  317.             break;
  318.             }
  319.         /*SetMode( 0x10 );  clear screen */
  320.         EraseRect ( &gPictWindow->portRect );
  321.         doedges(); /* display board edges */
  322.         doboard(); /* display the board */
  323.         }
  324.     }
  325.  
  326. /*
  327. ** enable this to catch ^C
  328. **
  329. **static void control_C () { / * handle ^C * /
  330. **    SetMode( mode ); / * restore original screen mode * /
  331. **    exit( 0 );
  332. **    }
  333. */
  334.  
  335. static void doedges () { /* display the board edges */
  336.     int r1, c1, r2, c2, i, z;
  337.  
  338.     z = zoomsize[zoom];
  339.     /* first, calculate their virtual screen positions */
  340.     r1 = MAXVERT+(Xrow*z); /* bottom edge */
  341.     c1 = MINHORZ-(Xcol*z); /* left edge */
  342.     r2 = MAXVERT-1-((Nrows-Xrow)*z); /* top edge */
  343.     c2 = MINHORZ+1+((Ncols-Xcol)*z); /* right edge */
  344.     if (r1 >= MINVERT && r1 <= MAXVERT) /* draw bottom edge */
  345.         for (i = c1; i <= c2; i++)
  346.             if (i >= MINHORZ && i <= MAXHORZ)
  347.                 Dot( E, r1, i );
  348.     if (c1 >= MINHORZ && c1 <= MAXHORZ) /* draw left edge */
  349.         for (i = r1; i >= r2; i--)
  350.             if (i >= MINVERT && i <= MAXVERT)
  351.                 Dot( E, i, c1 );
  352.     if (r2 >= MINVERT && r2 <= MAXVERT) /* draw top edge */
  353.         for (i = c1; i <= c2; i++)
  354.             if (i >= MINHORZ && i <= MAXHORZ)
  355.                 Dot( E, r2, i );
  356.     if (c2 >= MINHORZ && c2 <= MAXHORZ) /* draw right edge */
  357.         for (i = r1; i >= r2; i--)
  358.             if (i >= MINVERT && i <= MAXVERT)
  359.                 Dot( E, i, c2 );
  360.     }
  361.  
  362. static void doboard () { /* display the board on the screen, row by column */
  363.     int r, c, rp, cp, rpd, cpd, z;
  364.     long x, y;
  365.  
  366.     z = zoomsize[zoom];
  367.     rpd = MINVERT+z; /* top-most plottable row */
  368.     cpd = MAXHORZ-z; /* right-most plottable column */
  369.     for (r = Xrow, rp = MAXVERT-1; r < Nrows && rp >= rpd; r++, rp -= z) {
  370.         for (c = Xcol, cp = MINHORZ+1; c < Ncols && cp <= cpd;
  371.                 c++, cp += z) {
  372.             x = GetCell( r, c, TOP );
  373.             y = GetCell( r, c, BOTTOM );
  374.             if (x || y) /* only map if something is there */
  375.                 map( rp, cp, x, y );
  376.             }
  377.         }
  378.     }
  379.  
  380. struct x { /* group the bit templates for an object */
  381.     long t;            /* the object type    */
  382.     char t0[ZOOM0][ZOOM0];    /* tiny zoom template    */
  383.     char t1[ZOOM1][ZOOM1];    /* small zoom template    */
  384.     char t2[ZOOM2][ZOOM2];    /* medium zoom template    */
  385.     char t3[ZOOM3][ZOOM3];    /* large zoom template    */
  386.     };
  387.  
  388. extern struct x y1[];  /* hole templates        */
  389. extern struct x y2[];  /* hole-related templates    */
  390. extern struct x y3[];  /* non-hole-related templates    */
  391.  
  392. extern int z1;  /* number of hole types            */
  393. extern int z2;  /* number of hole-related types        */
  394. extern int z3;  /* number of non-hole-related types    */
  395.  
  396. #define domap1(v,c)    { for (i = 0; i < z1; i++) { \
  397.                 if (v & (y1[i].t)) { \
  398.                     if (zoom == 0) \
  399.                         plot0( rp, cp, y1[i].t0, c );\
  400.                     else if (zoom == 1) \
  401.                         plot1( rp, cp, y1[i].t1, c );\
  402.                     else if (zoom == 2) \
  403.                         plot2( rp, cp, y1[i].t2, c );\
  404.                     else if (zoom == 3) \
  405.                         plot3( rp, cp, y1[i].t3, c );\
  406.                     } \
  407.                 } } \
  408.  
  409. #define domap2(v,c)    { for (i = 0; i < z2; i++) { \
  410.                 if (v & (y2[i].t)) { \
  411.                     if (zoom == 0) \
  412.                         plot0( rp, cp, y2[i].t0, c );\
  413.                     else if (zoom == 1) \
  414.                         plot1( rp, cp, y2[i].t1, c );\
  415.                     else if (zoom == 2) \
  416.                         plot2( rp, cp, y2[i].t2, c );\
  417.                     else if (zoom == 3) \
  418.                         plot3( rp, cp, y2[i].t3, c );\
  419.                     } \
  420.                 } } \
  421.  
  422. #define domap3(v,c)    { for (i = 0; i < z3; i++) { \
  423.                 if (v & (y3[i].t)) { \
  424.                     if (zoom == 0) \
  425.                         plot0( rp, cp, y3[i].t0, c );\
  426.                     else if (zoom == 1) \
  427.                         plot1( rp, cp, y3[i].t1, c );\
  428.                     else if (zoom == 2) \
  429.                         plot2( rp, cp, y3[i].t2, c );\
  430.                     else if (zoom == 3) \
  431.                         plot3( rp, cp, y3[i].t3, c );\
  432.                     } \
  433.                 } } \
  434.  
  435. static void map ( rp, cp, v0, v1 ) /* map a cell */
  436.     int rp, cp;
  437.     long v0, v1;
  438.     {
  439.     int i;
  440.  
  441.     if (v0 & HOLE) {
  442.         domap1( v0, H ); /* plot the hole */
  443.         if (v1 && (sides & 2)) /* plot backside? */
  444.             domap2( v1, B );
  445.         if (v0 && (sides & 1)) /* plot frontside? */
  446.             domap2( v0, F );
  447.         }
  448.     else {
  449.         if (v1 && (sides & 2)) /* plot backside? */
  450.             domap3( v1, B );
  451.         if (v0 && (sides & 1)) /* plot frontside? */
  452.             domap3( v0, F );
  453.         }
  454.     }
  455.  
  456. static void plot0 ( rp, cp, obj, color ) /* plot a 3x3 template */
  457.     int rp, cp;
  458.     char obj[ZOOM0][ZOOM0];
  459.     int color;
  460.     {
  461.     int r, c;
  462.  
  463.     for (r = 0; r < ZOOM0; r++)
  464.         for (c = 0; c < ZOOM0; c++)
  465.             if (obj[r][c])
  466.                 Dot( color, rp-r, cp+c );
  467.     }
  468.  
  469. static void plot1 ( rp, cp, obj, color ) /* plot a 6x6 template */
  470.     int rp, cp;
  471.     char obj[ZOOM1][ZOOM1];
  472.     int color;
  473.     {
  474.     int r, c;
  475.  
  476.     for (r = 0; r < ZOOM1; r++)
  477.         for (c = 0; c < ZOOM1; c++)
  478.             if (obj[r][c])
  479.                 Dot( color, rp-r, cp+c );
  480.     }
  481.  
  482. static void plot2 ( rp, cp, obj, color ) /* plot a 10x10 template */
  483.     int rp, cp;
  484.     char obj[ZOOM2][ZOOM2];
  485.     int color;
  486.     {
  487.     int r, c;
  488.  
  489.     for (r = 0; r < ZOOM2; r++)
  490.         for (c = 0; c < ZOOM2; c++)
  491.             if (obj[r][c])
  492.                 Dot( color, rp-r, cp+c );
  493.     }
  494.  
  495. static void plot3 ( rp, cp, obj, color ) /* plot an 18x18 template */
  496.     int rp, cp;
  497.     char obj[ZOOM3][ZOOM3];
  498.     int color;
  499.     {
  500.     int r, c;
  501.  
  502.     for (r = 0; r < ZOOM3; r++)
  503.         for (c = 0; c < ZOOM3; c++)
  504.             if (obj[r][c])
  505.                 Dot( color, rp-r, cp+c );
  506.     }
  507.